package com.hdmp.auth.shiro;

import com.hdmp.auth.entity.SysPermissionEntity;
import com.hdmp.auth.entity.SysRoleEntity;
import com.hdmp.auth.entity.SysUserEntity;
import com.hdmp.auth.service.SysRoleService;
import com.hdmp.auth.service.SysPermissionService;
import com.hdmp.auth.service.SysUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author BigFan
 * @create 2018/11/14 7:43 PM
 */
public class UserRealm extends AuthorizingRealm {

    @Autowired
    @Lazy
    SysUserService userService;

    @Autowired
    @Lazy
    SysPermissionService menuService;

    @Autowired
    SysRoleService roleService;


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        ShiroUser shiroUser = (ShiroUser) principalCollection.getPrimaryPrincipal();
        List<SysPermissionEntity> menuEntities = menuService.queryMenuByUserId(shiroUser.getId());
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        Set<String> permis = menuEntities
                .stream()
                .map(c -> c.getMethod())
                .collect(Collectors.toSet());


        List<SysRoleEntity> roleEntities = roleService.queryRoleByUserDbid(shiroUser.getId());

        Set<String> roleSet = roleEntities
                .stream()
                .map(c -> c.getName())
                .collect(Collectors.toSet());

        info.setRoles(roleSet);
        info.setStringPermissions(permis);

        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        SysUserEntity userEntity = userService.queryByName(username);
        if (userEntity == null) {
            throw new UnknownAccountException();
        }
        ShiroUser shiroUser = new ShiroUser();
        shiroUser.setName(userEntity.getName());
        shiroUser.setId(userEntity.getDbid());
        shiroUser.setUsername(userEntity.getUsername());

        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(shiroUser, userEntity.getPassword(),
                ByteSource.Util.bytes(userEntity.getCredentialsSalt()), getName());
        return authenticationInfo;
    }
}
